/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mobilevikings.app;

import com.mobilevikings.app.api.ApiConnection;
import com.mobilevikings.app.callhistory.CallHistoryFunction;
import com.mobilevikings.app.debugger.DebugFunction;
import com.mobilevikings.app.simbalance.SimBalanceFunction;
import com.mobilevikings.app.topuphistory.TopUpHistoryFunction;
import com.mobilevikings.util.Properties;
import com.mobilevikings.util.PropertiesFactory;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

/**
 *
 * @author Jeroen
 */
public class JavaViking extends MIDlet implements CommandListener {

    private boolean ADD_DEBUGFUNCTION = false;
    private final int MENU_FUNCTIONS = 3;
    private final int MENU_ITEMS_LENGTH = MENU_FUNCTIONS + (ADD_DEBUGFUNCTION ? 1 : 0);
    private String NAME_RECORDSTORE = "credentials";
    private Display display;
    private TextField mTxtUsername;
    private TextField mTxtPassword;
    private boolean mCancelled;
    private Properties properties;
    private Form mLogInForm;
    private ChoiceGroup mOptions;
    private Command mCmdSignIn;
    private Command mCmdExit;
    private Command mCmdOk;
    private Command mCmdCancel;
    private Alert mAlrtBusy;
    private Alert mAlrtFailed;
    private String[] mMenuItems;
    private Function[] mMenuFunctions;
    private List mMainMenu;
    private ApiConnection api;

    public JavaViking() {
        properties = PropertiesFactory.getProperties();
        api = ApiConnection.getInstance();
        //commands
        mCmdSignIn = new Command(properties.get("INLOGFORM_SIGN_IN"), Command.OK, 0);
        mCmdExit = new Command(properties.get("EXIT"), Command.EXIT, 1);
        mCmdOk = new Command(properties.get("OK"), Command.OK, 0);
        mCmdCancel = new Command(properties.get("CANCEL"), Command.CANCEL, 1);

        //form
        mLogInForm = new Form(properties.get("INLOGFORM_TITLE"));
        mTxtUsername = new TextField(properties.get("INLOGFORM_USERNAME"), "", 40, TextField.ANY);
        mTxtPassword = new TextField(properties.get("INLOGFORM_PASSWORD"), "", 40, TextField.PASSWORD);
        String[] cOptions = {
            properties.get("INLOGFORM_SAVE")
        };
        mOptions = new ChoiceGroup(properties.get("OPTIONS"), ChoiceGroup.MULTIPLE, cOptions, null);
        mOptions.setSelectedIndex(0, true);
        mLogInForm.append(mTxtUsername);
        mLogInForm.append(mTxtPassword);
        mLogInForm.append(mOptions);
        mLogInForm.setCommandListener(this);
        mLogInForm.addCommand(mCmdSignIn);
        mLogInForm.addCommand(mCmdExit);

        //alerts
        mAlrtBusy = new Alert(properties.get("APP_NAME"), properties.get("INLOGFORM_BUSY"), null, AlertType.INFO);
        mAlrtBusy.setTimeout(Alert.FOREVER);
        mAlrtBusy.setIndicator(new Gauge(null, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING));
        mAlrtBusy.addCommand(mCmdCancel);
        mAlrtBusy.setCommandListener(this);
        mAlrtFailed = new Alert(properties.get("APP_NAME"), properties.get("INLOGFORM_FAILED"), null, AlertType.ERROR);
        mAlrtFailed.setTimeout(Alert.FOREVER);

        //mainmenu
        mMenuItems = new String[MENU_ITEMS_LENGTH];
        mMenuItems[0] = properties.get("SIMBALANCE");
        mMenuItems[1] = properties.get("CALL_HISTORY");
        mMenuItems[2] = properties.get("TOPUP_HISTORY");


        if (ADD_DEBUGFUNCTION) {
            mMenuItems[MENU_FUNCTIONS] = "DEBUG";
        }
        mMenuFunctions = null;
        mMainMenu = new List(properties.get("MENU_TITLE"), List.IMPLICIT, mMenuItems, null);
        mMainMenu.setCommandListener(this);
        mMainMenu.addCommand(mCmdOk);
        mMainMenu.addCommand(mCmdExit);
    }

    protected void startApp() throws MIDletStateChangeException {
        display = Display.getDisplay(this);
        display.setCurrent(mLogInForm);
        api = ApiConnection.getInstance();
        retrieveData();
    }

    protected void pauseApp() {
    }

    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
    }

    /**
     * Initializes all the functions in the menu
     */
    private void initFunctions() {
        mMenuFunctions = new Function[MENU_ITEMS_LENGTH];
        mMenuFunctions[0] = new SimBalanceFunction(display);
        mMenuFunctions[1] = new CallHistoryFunction(display);
        mMenuFunctions[2] = new TopUpHistoryFunction(display);
        if (ADD_DEBUGFUNCTION) {
            mMenuFunctions[MENU_FUNCTIONS] = DebugFunction.getInstance(display);
        }
    }

    /**
     * Will save the nickname and password filled in in the textfields into a recordstore
     */
    private void saveData() {
        api.setUsername(mTxtUsername.getString());
        api.setPassword(mTxtPassword.getString());
        RecordStore rs = null;
        deleteData();
        try {
            rs = RecordStore.openRecordStore(NAME_RECORDSTORE, true);
            if (rs != null) {
                byte[] userBytes = mTxtUsername.getString().getBytes();
                byte[] passBytes = mTxtPassword.getString().getBytes();
                rs.addRecord(userBytes, 0, userBytes.length);
                rs.addRecord(passBytes, 0, passBytes.length);
                rs.closeRecordStore();
            }
        } catch (RecordStoreException ex) {
        }
    }

    /**
     * Will try to retrieve the nickname and password from a recordstore
     */
    private void retrieveData() {
        RecordStore rs = null;
        try {
            rs = RecordStore.openRecordStore(NAME_RECORDSTORE, false);
            if (rs != null && rs.getNumRecords() >= 2) {
                mTxtUsername.setString(new String(rs.getRecord(1)));
                mTxtPassword.setString(new String(rs.getRecord(2)));
            }
        } catch (NullPointerException ex) {
            ex.printStackTrace();
            mTxtUsername.setString("");
            mTxtPassword.setString("");
        } catch (RecordStoreException ex) {
        } finally { //Important to close the recordstore! (to make it possible to delete it)
            if (rs != null) {
                try {
                    rs.closeRecordStore();
                } catch (RecordStoreException ex) {
                }
            }
        }
    }

    /**
     * Will delete the nickname and password, stored in a recordstore
     */
    private void deleteData() {
        api.setUsername(mTxtUsername.getString());
        api.setPassword(mTxtPassword.getString());
        try {
            RecordStore.deleteRecordStore(NAME_RECORDSTORE);
        } catch (RecordStoreException ex) {
        }
    }

    /**
     * Handles the commands
     * @param c the command
     * @param d the Displayable
     */
    public void commandAction(Command c, Displayable d) {
        if (c.getCommandType() == Command.EXIT) {
            notifyDestroyed();
        }
        else {
            if (d == mLogInForm) {
                if (mOptions.isSelected(0)) { //first is Save-option
                    saveData();
                }
                else {
                    deleteData();
                }
                display.setCurrent(mMainMenu);
            }
            else if (d == mMainMenu) { //menu
                if (mMenuFunctions == null) {
                    initFunctions();
                }
                int index = mMainMenu.getSelectedIndex();
                mMenuFunctions[index].show();
            }
            else if (d == mAlrtBusy) {
                mCancelled = true;
                display.setCurrent(mLogInForm);
            }
        }

    }
}
